#include "bsp_iic.h"


/**
 * @description: IIC通信延时
 * @return {*}
 */
static void bsp_iic_delay(void)
{
	uint8_t t=3;
	while(t--);
}

/**
 * @description: 发送IIC起始信号
 * @return {*}
 */
void bsp_iic_start(void)
{
	IIC_SDA_HIGH();
	IIC_SCL_HIGH();
	bsp_iic_delay();
	IIC_SDA_LOW();
	bsp_iic_delay();
	IIC_SCL_LOW();
	bsp_iic_delay();
}

/**
 * @description: 发送IIC结束信号
 * @return {*}
 */
void bsp_iic_stop(void)
{
	IIC_SDA_LOW();
	IIC_SCL_HIGH();
	bsp_iic_delay();
	IIC_SDA_HIGH();
}

/**
 * @description: IIC通信应答等待
 * @return {*}
 */
uint8_t bsp_iic_wait_ack(void) //测数据信号的电平
{
	uint8_t ack = IIC_ACK;
	uint8_t ack_timeout;
	
	IIC_SCL_LOW(); 			//拉低时钟线，准备好传输第9个时钟脉冲
	bsp_iic_delay();
	IIC_SDA_HIGH(); 		//拉高数据线
	bsp_iic_delay();
	IIC_SCL_HIGH(); 		//拉高时钟线，传输第9个时钟脉冲
	bsp_iic_delay();
	while (IIC_SDA_READ()) {
        ack_timeout++;
        // 判断等待是否超时
        if (ack_timeout >= 10) {
			ack = IIC_NO_ACK; 	//如果从机拉拉高数据线，反馈无效应答位Ack
            break;
        }
    }
	
	IIC_SCL_LOW(); //拉低时钟线，9个脉冲传输完毕
	bsp_iic_delay();
	
	return ack; //返回应答
}

/**
 * @description: IIC通信发送一个字节
 * @return {*}
 */
void bsp_iic_send_byte(uint8_t dat)
{
	uint8_t i;
	for(i=0;i<8;i++)
	{
		IIC_SCL_LOW();//将时钟信号设置为低电平
		if(dat&0x80)//将dat的8位从最高位依次写入
		{
			IIC_SDA_HIGH();
		}
		else
		{
			IIC_SDA_LOW();
		}
		dat<<=1;
		bsp_iic_delay();
		IIC_SCL_HIGH();
		bsp_iic_delay();
	}
}

/**
 * @description: IIC通信发送应答信号
 * @return {*}
 */
void bsp_iic_send_ack(void)
{

	IIC_SCL_LOW();//将时钟信号设置为低电平
	bsp_iic_delay();

	IIC_SDA_LOW();
	bsp_iic_delay();

	IIC_SCL_HIGH();
	bsp_iic_delay();

    IIC_SCL_LOW();//将时钟信号设置为低电平
	bsp_iic_delay();

}

/**
 * @description: IIC通信发送非应答信号
 * @return {*}
 */
void bsp_iic_send_noack(void)
{

	IIC_SCL_LOW();//将时钟信号设置为低电平
	bsp_iic_delay();

	IIC_SDA_HIGH();
	bsp_iic_delay();

	IIC_SCL_HIGH();
	bsp_iic_delay();

    IIC_SCL_LOW();//将时钟信号设置为低电平
	bsp_iic_delay();
}

/**
 * @description: IIC通信读取一个字节数据
 * @return {*}
 */
uint8_t bsp_iic_read_byte(void)
{
    uint8_t ret = 0;
    uint8_t i = 0;
	
	IIC_SDA_HIGH();
    for (i = 0; i < 8; i++) {
        IIC_SCL_HIGH();
        bsp_iic_delay();
        ret <<= 1;
        if (IIC_SDA_READ()) {
            ret |= 0x01;
        }
		IIC_SCL_LOW();//将时钟信号设置为低电平
		IIC_SDA_HIGH();
		bsp_iic_delay();
    }
    return ret;
}

/**
 * @description: IIC通信检查设备状态
 * @return {*}
 */
uint8_t bsp_iic_check_dev(uint8_t _addr)
{
	uint8_t ucAck;
	
	bsp_iic_start();		/* 发送启动信号 */
	/* 发送设备地址+读写控制bit（0 = w， 1 = r) bit7 先传 */
	bsp_iic_send_byte(_addr | IIC_DATA_WRITE);
	ucAck = bsp_iic_wait_ack();		/* 检测设备的ACK应答 */

	bsp_iic_stop();			/* 发送停止信号 */

	return ucAck;
}

